package com.wdullaer.datetimepickerexampleohos;

import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Checkbox;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.RadioContainer;
import ohos.agp.components.Text;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import com.wdullaer.materialdatetimepicker.JalaliCalendar;
import com.wdullaer.materialdatetimepicker.Utils;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;

import java.io.IOException;
import java.util.Calendar;

/**
 * A simple {@link Fraction} subclass.
 */
public class DatePickerFraction extends Fraction implements DatePickerDialog.OnDateSetListener {

    private static final String TAG = "MonthFragment";
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 1234567, TAG);

    private Text dateTextView;
    private Checkbox modeDarkDate;
    private Checkbox modeCustomAccentDate;
    private Checkbox vibrateDate;
    private Checkbox dismissDate;
    private Checkbox titleDate;
    private Checkbox showYearFirst;
    private Checkbox showVersion2;
    private Checkbox switchOrientation;
    private Checkbox limitSelectableDays;
    private Checkbox highlightDays;
    private Checkbox defaultSelection;
    private DatePickerDialog dpd;
    Font font;
    DatePickerDialog.Type calendarType;

    public DatePickerFraction() {
    }

    @Override
    protected Component onComponentAttached(LayoutScatter scatter, ComponentContainer container, Intent intent) {
        Component component = scatter.parse(ResourceTable.Layout_datepicker_layout, container, false);

        // Find our Component instances
        dateTextView = (Text) component.findComponentById(ResourceTable.Id_date_textview);
        Button dateButton = (Button) component.findComponentById(ResourceTable.Id_date_button);
        modeDarkDate = (Checkbox) component.findComponentById(ResourceTable.Id_mode_dark_date);
        modeCustomAccentDate = (Checkbox) component.findComponentById(ResourceTable.Id_mode_custom_accent_date);
        vibrateDate = (Checkbox) component.findComponentById(ResourceTable.Id_vibrate_date);
        dismissDate = (Checkbox) component.findComponentById(ResourceTable.Id_dismiss_date);
        titleDate = (Checkbox) component.findComponentById(ResourceTable.Id_title_date);
        showYearFirst = (Checkbox) component.findComponentById(ResourceTable.Id_show_year_first);
        showVersion2 = (Checkbox) component.findComponentById(ResourceTable.Id_show_version_2);
        switchOrientation = (Checkbox) component.findComponentById(ResourceTable.Id_switch_orientation);
        limitSelectableDays = (Checkbox) component.findComponentById(ResourceTable.Id_limit_dates);
        highlightDays = (Checkbox) component.findComponentById(ResourceTable.Id_highlight_dates);
        defaultSelection = (Checkbox) component.findComponentById(ResourceTable.Id_default_selection);

        try {
            font = Utils.getFont(getFractionAbility(), "resources/rawfile/fonts/" + "IRANSansMobile(FaNum).ttf");
        } catch (IOException e) {
            e.getMessage();
        }
        final int[] selectedIndex = {0};
        RadioContainer radioContainer = (RadioContainer) component.findComponentById(ResourceTable.Id_calendar_type_radio_container);
        radioContainer.mark(0);
        radioContainer.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(RadioContainer radioContainer, int index) { // TODO 待调试验证
                selectedIndex[0] = index;
            }
        });

        // Show a datepicker when the dateButton is clicked
        dateButton.setClickedListener(c -> {
            //TODO 源库代码，导致闪退
            Calendar now = Calendar.getInstance();
            if (defaultSelection.isChecked()) {
                now.add(Calendar.DATE, 7);
            }

            if (selectedIndex[0] == 0) {
                calendarType = DatePickerDialog.Type.JALALI;
            } else {
                calendarType = DatePickerDialog.Type.GREGORIAN;
            }

            switch (calendarType) {
                case GREGORIAN:
                    now = Calendar.getInstance();
                    break;

                case JALALI:
                    now = JalaliCalendar.getInstance();
                    break;
            }
            /*
            It is recommended to always create a new instance whenever you need to show a Dialog.
            The sample app is reusing them because it is useful when looking for regressions
            during testing
             */
            HiLog.warn(LABEL, "### on dateButton click");
            if (dpd == null) {
                HiLog.warn(LABEL, "### dpd == null");
                dpd = DatePickerDialog.newInstance(
                    calendarType,
                    container.getContext(),
                    DatePickerFraction.this,
                    now.get(Calendar.YEAR),
                    now.get(Calendar.MONTH),
                    now.get(Calendar.DAY_OF_MONTH)
                );
            } else {
                HiLog.warn(LABEL, "### dpd != null");
                dpd.setCalendarType(calendarType);
                dpd.initialize(
                    DatePickerFraction.this,
                    now.get(Calendar.YEAR),
                    now.get(Calendar.MONTH),
                    now.get(Calendar.DAY_OF_MONTH)
                );
            }
            switch (calendarType) {
                case GREGORIAN:
                    dpd.setFont(null);
                    break;

                case JALALI:
                    dpd.setFont(font);
                    break;
            }

            dpd.setAlignment(LayoutAlignment.CENTER);
            dpd.setThemeDark(modeDarkDate.isChecked());
            dpd.vibrate(vibrateDate.isChecked());
            dpd.dismissOnPause(dismissDate.isChecked());
            dpd.showYearPickerFirst(showYearFirst.isChecked());
            HiLog.warn(LABEL, "### showVersion2.isChecked():" + showVersion2.isChecked());
            dpd.setVersion(showVersion2.isChecked() ? DatePickerDialog.Version.VERSION_2 : DatePickerDialog.Version.VERSION_1);
            if (modeCustomAccentDate.isChecked()) {
                dpd.setAccentColor(Color.getIntColor("#9C27B0"));
            }
            if (titleDate.isChecked()) {
                switch (calendarType) {
                    case GREGORIAN:
                        dpd.setTitle("DatePicker Title");
                        break;
                    case JALALI:
                        dpd.setTitle("عنوان انتخابگر تاریخ");
                        break;
                }
            }
            if (highlightDays.isChecked()) {
                Calendar date1 = Calendar.getInstance();
                Calendar date2 = Calendar.getInstance();
                date2.add(Calendar.WEEK_OF_MONTH, -1);
                Calendar date3 = Calendar.getInstance();
                date3.add(Calendar.WEEK_OF_MONTH, 1);
                Calendar[] days = {date1, date2, date3};
                dpd.setHighlightedDays(days);
            }
            if (limitSelectableDays.isChecked()) {
                Calendar[] days = new Calendar[13];
                for (int i = -6; i < 7; i++) {
                    Calendar day;
                    switch (calendarType) {
                        case JALALI:
                            day = JalaliCalendar.getInstance();
                            break;

                        default:
                            day = Calendar.getInstance();
                            break;
                    }
                    day.add(Calendar.DAY_OF_MONTH, i * 2);
                    days[i + 6] = day;
                }
                dpd.setSelectableDays(days);
            }
            if (switchOrientation.isChecked()) {
                if (dpd.getVersion() == DatePickerDialog.Version.VERSION_1) {
                    dpd.setScrollOrientation(DatePickerDialog.ScrollOrientation.HORIZONTAL);
                } else {
                    dpd.setScrollOrientation(DatePickerDialog.ScrollOrientation.VERTICAL);
                }
            }
            dpd.setOnCancelListener(dialog -> {
                HiLog.warn(LABEL, "Dialog was cancelled");
                dpd = null;
            });
            dpd.show();
        });

        return component;
    }

    @Override
    protected void onStop() {
        super.onStop();
        dpd = null;
    }

    @Override
    protected void onBackground() {
        super.onBackground();
        if (dpd != null) {
            dpd.onBackground(dpd);
            dpd = null;
        }
    }

    @Override
    protected void onActive() {
        super.onActive();
        if (dpd != null) dpd.setOnDateSetListener(this);
    }

    @Override
    public void onDateSet(DatePickerDialog dialog, int year, int monthOfYear, int dayOfMonth) {
        String date = "You picked the following date: " + dayOfMonth + "/" + (++monthOfYear) + "/" + year;
        dateTextView.setText(date);
        dpd = null;
    }
}
